#include "DecoderImp.h"
using namespace std;

bool operator< (const DataCode& lf, const DataCode& rf)
{
	if(lf._bitSize < rf._bitSize)
		return true;
	else if(lf._bitSize == rf._bitSize)
		return lf._code < rf._code;
	else
		return false;
}

DecoderImp::DecoderImp(void) : _curBit(7), _curByte(0), _decodeCount(0)
{
	_code._code = 0;
	_code._bitSize = 0;
}

DecoderImp::~DecoderImp(void)
{
}

bool DecoderImp::ReadDictionary(FileReader* reader)
{
	int dictItemCount = reader->ReadInt();
	if(reader->Eof()) return false;
	for(int i = 0; i < dictItemCount; ++i)
	{
		DictItem di;
		di._code._bitSize = reader->ReadInt();
		di._code._code = reader->ReadInt();
		di._data._dataSize = reader->ReadInt();
		di._data._data = new BYTE[di._data._dataSize];
		for(int j = 0; j < di._data._dataSize; ++j)
		{
			di._data._data[j] = reader->ReadByte();
		}
		_dictionary[di._code] = di._data;
	}
	return true;
}

void DecoderImp::SetCodeBlock(BYTE* codeBlock, int count)
{
	_codeBuffer = codeBlock;
	_bufferSize = count;
	_curByte = 0;
}

bool DecoderImp::GetNextData(DictData* dd)
{
	while(_curByte < _bufferSize && _decodeCount < _codeSum)
	{
		_code._bitSize++;
		_code._code = (_code._code << 1) + ((_codeBuffer[_curByte] & (1<<_curBit)) >> _curBit--);
		if(_curBit < 0)
		{
			_curBit = 7;
			_curByte++;
		}
		if(_dictionary.count(_code) > 0)
		{
			map<DataCode, DictData>::iterator it = _dictionary.find(_code);
			dd->_data = it->second._data;
			dd->_dataSize= it->second._dataSize;
			_code._code = 0;
			_code._bitSize = 0;
			_decodeCount++;
			return true;
		}
	}
	return false;
}